package no.uis.maven.liferay.servicebuilder;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.File;

import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;

import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.tools.servicebuilder.ServiceBuilder;
import com.liferay.portal.util.InitUtil;

/**
 * @description A Mojo that calls Liferay's ServiceBuilder.
 * @goal build
 * @phase generate-sources
 * @pluginName servicebuilder
 */
public class ServiceBuilderMojo extends AbstractMojo {

  /**
   * Maven Project. 
   * 
   * @parameter expression="${project}"
   * @readonly
   * @required
   */
  private MavenProject project;

  /**
   * The service descriptor.
   * 
   * @parameter expression="${project.basedir}/src/main/scripts/service.xml"
   * @required
   */
  private String serviceXml;

  /**
   * Hibernate mapping file.
   * 
   * @parameter default-value="META-INF/portlet-hbm.xml"
   * @required
   */
  private String hbmFileName;

  /**
   * Hibernate model hints.
   * 
   * @parameter default-value="META-INF/portlet-model-hints.xml"
   * @required
   */
  private String modelHintsFileName;

  /**
   * Spring file.
   * 
   * @parameter default-value="META-INF/portlet-spring.xml"
   * @required
   */
  private String springFileName;

  /**
   * Spring base file.
   * 
   * @parameter default-value="META-INF/base-spring.xml"
   * @required
   */
  private String springBaseFileName;

  /**
   * Spring dynamic data source file.
   * 
   * @parameter default-value="META-INF/dynamic-data-source-spring.xml"
   * @required
   */
  private String springDynamicDataSourceFileName;

  /**
   * Spring Hibernate file.
   * 
   * @parameter default-value="META-INF/hibernate-spring.xml"
   * @required
   */
  private String springHibernateFileName;

  /**
   * Spring infrastructure file.
   * 
   * @parameter default-value="META-INF/infrastructure-spring.xml"
   * @required
   */
  private String springInfrastructureFileName;

  /**
   * API directory.
   * 
   * @parameter expression="${project.basedir}/target/generated-sources/servicebuilder/build/src/api"
   * @required
   */
  private String apiDir;

  /**
   * Impl Dir.
   * 
   * @parameter expression="${project.build.sourceDirectory}"
   * @required
   */
  private String implDir;

  /**
   * Directory for generated Spring files.
   * 
   * @parameter expression="${project.basedir}/target/generated-sources/servicebuilder/build/spring"
   * @required
   */
  private String springDir;
  
  /**
   * Location of the hibernate config files.
   * @parameter expression="${project.basedir}/target/generated-sources/servicebuilder/build/hibernate"
   * @required
   */
  private String hibernateDir;
  
  /**
   * Web app's root folder.  
   * @parameter expression="${project.basedir}/src/main/webapp"
   */
  private String webappDir;
  
  /**
   * JSON File.
   * 
   * @parameter expression="${project.artifactId}.js"
   */
  private String jsonFileName;

  /**
   * Hessian Remoting file.
   * 
   * @parameter default-value="remoting-servlet.xml"
   */
  private String remotingFileName;

  /**
   * SQL file Directory.
   * 
   * @parameter expression="${project.basedir}/src/main/webapp/WEB-INF/sql"
   */
  private String sqlDir;

  /**
   * SQL filename.
   * 
   * @parameter default-value="tables.sql"
   */
  private String sqlFileName;

  /**
   * SQL indexes.
   * 
   * @parameter default-value="indexes.sql"
   */
  private String sqlIndexesFileName;

  /**
   * SQL indexes properties.
   * 
   * @parameter default-value="indexes.properties"
   */
  private String sqlIndexesPropertiesFileName;

  /**
   * SQL sequences file.
   * 
   * @parameter default-value="sequences.sql"
   */
  private String sqlSequencesFileName;

  /**
   * Auto namespaces for tables.
   * 
   * @parameter default-value="true"
   */
  private boolean autoNamespaceTables;

  /**
   * Bean Locator Util class. This can either be
   * <ul>
   * <li>{@link com.liferay.util.bean.PortletBeanLocatorUtil} for portlets or</li>
   * <li>{@link com.liferay.portal.kernel.bean.BeanLocatorUtil} for stand-alone services</li>
   * </ul>
   * 
   * @parameter default-value="com.liferay.util.bean.PortletBeanLocatorUtil"
   * @required
   */
  private String beanLocatorUtil;

  /**
   * PropsUtil class. This can either be
   * <ul>
   * <li>{@link com.liferay.util.service.ServiceProps} for portlets or</li>
   * <li>{@link com.liferay.portal.util.PropsUtil} for stand-alone services</li>
   * </ul>
   * 
   * @parameter default-value="com.liferay.util.service.ServiceProps"
   * @required
   */
  private String propsUtil;

  /**
   * Plugin name.
   * 
   * @parameter expression="${project.artifactId}"
   * @required
   */
  private String pluginName;

  /**
   * Test dir.
   * 
   * @readonly
   * @parameter expression="${project.basedir}/target/generated-test-sources/servicebuilder/build"
   */
  private String testDir;

  /**
   * Create test classes.
   * @parameter default-value="false" 
   */
  private boolean createTests;

  public void execute() throws MojoExecutionException {

    File hbmFile = new File(hibernateDir, hbmFileName); 
    File modelHintsFile = new File(hibernateDir, modelHintsFileName);
    File springFile = new File(springDir, springFileName);
    File springBaseFile = new File(springDir, springBaseFileName);
    File springDynamicDataSourceFile = new File(springDir, springDynamicDataSourceFileName);
    File springHibernateFile = new File(springDir, springHibernateFileName);
    File springInfrastructureFile = new File(springDir, springInfrastructureFileName);
    File jsonFile = new File(webappDir, jsonFileName);
    
    project.addCompileSourceRoot(implDir);
    project.addCompileSourceRoot(apiDir);
    addDirToResources(hibernateDir);
    addDirToResources(springDir);
    if (createTests && testDir != null && !testDir.trim().isEmpty()) {
      project.addTestCompileSourceRoot(this.testDir);
    }

    InitUtil.initWithSpring();

    if (Validator.isNotNull(sqlDir)) {
      File f = new File(sqlDir);
      f.mkdirs();
    }
    // TODO wait until http://issues.liferay.com/browse/LPS-4958 is resolved and set the location of 
    // service.properties

    ServiceBuilder builder = new ServiceBuilder(
      serviceXml, 
      hbmFile.getPath(), 
      modelHintsFile.getPath(), 
      springFile.getPath(), 
      springBaseFile.getPath(),
      springDynamicDataSourceFile.getPath(), 
      springHibernateFile.getPath(), 
      springInfrastructureFile.getPath(), 
      apiDir, 
      implDir,
      jsonFile.getPath(), 
      remotingFileName, 
      sqlDir, 
      sqlFileName, 
      sqlIndexesFileName, 
      sqlIndexesPropertiesFileName,
      sqlSequencesFileName, 
      autoNamespaceTables, 
      beanLocatorUtil, 
      propsUtil, 
      pluginName, 
      createTests ? testDir : null, 
      true);

    if (builder == null) {
      throw new RuntimeException("Cannot create ServiceBuilder");
    }
  }

  private void addDirToResources(String dir) {
    Resource res = new Resource();
    res.setDirectory(dir);
    res.addInclude("**/**");
    res.setTargetPath(project.getBuild().getOutputDirectory());
    project.addResource(res);
  }
}
